#include "dbconfig.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define MAIN_SECTION    "Global"

// int型
#define GETINT(section, name, value) \
    value = cfg.GetInt(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	}

// char数组
#define GETSTR(section, name, value) \
    s = cfg.GetString(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	} \
    iRet = ct_snprintf(CT_STRSIZE(value), "%s", s.c_str()); \
    if (iRet < 0) \
    { \
        CT_THROW(("[%s]%s too long, over %d", MAIN_SECTION, name, sizeof(value))); \
    }

// CTSizeString数组
#define GETSIZESTRING(section, name, value) \
    s = cfg.GetString(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	} \
    iRet = value.Set("%s", s.c_str()); \
    if (iRet < 0) \
    { \
        CT_THROW(("[%s]%s too long, over %d", MAIN_SECTION, name, sizeof(value))); \
    }

// string
#define GETSTRING(section, name, value) \
    value = cfg.GetString(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	}

/*-- Begin: Added by LincLiu on 2009-10-28: Define macro to get config value from dedicated file --*/
// int型
#define GETINTFROMFILE(cfgFile, section, name, value) \
    value = cfg.GetInt(cfgFile, section, name, &iRet); \
    if (iRet) \
    { \
    CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
    }

#define GETUSHORTFROMFILE(cfgFile, section, name, value) \
    value = (unsigned short)cfg.GetInt(cfgFile, section, name, &iRet); \
    if (iRet) \
    { \
    CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
    }

// char数组
#define GETSTRFROMFILE(cfgFile, section, name, value) \
    s = cfg.GetString(cfgFile, section, name, &iRet); \
    if (iRet) \
    { \
    CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
    } \
    iRet = ct_snprintf(CT_STRSIZE(value), "%s", s.c_str()); \
    if (iRet < 0) \
    { \
    CT_THROW(("[%s]%s too long, over %d", MAIN_SECTION, name, sizeof(value))); \
    }

// CTSizeString数组
#define GETSIZESTRINGFROMEFILE(cfgFile, section, name, value) \
    s = cfg.GetString(cfgFile, section, name, &iRet); \
    if (iRet) \
    { \
    CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
    } \
    iRet = value.Set("%s", s.c_str()); \
    if (iRet < 0) \
    { \
    CT_THROW(("[%s]%s too long, over %d", MAIN_SECTION, name, sizeof(value))); \
    }

// string
#define GETSTRINGFROMFILE(cfgFile, section, name, value) \
    value = cfg.GetString(cfgFile, section, name, &iRet); \
    if (iRet) \
    { \
    CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
    }


/*-- End: Added by LincLiu on 2009-10-28: Define macro to get config value from dedicated file --*/

int CDBConfig::LoadConfig()
{
    CTConfig cfg;
    string s;
    int iRet = cfg.LoadConfig(FILE_CONFIG);
    if (iRet)
    {
        CT_THROW(("LoadConfig failed: %d", iRet));
    }

    GETSIZESTRING(MAIN_SECTION, "MgrShmKey", MgrShmKey);
    GETSIZESTRING(MAIN_SECTION, "UptShmKey", UptShmKey);
//    Ftok(MgrShmKey.GetBuffer(), MgrShmKey.GetBufferLen());

    GETSIZESTRING(MAIN_SECTION, "EnpFrontEndShmKey", EnpFrontEndShmKey);
//    Ftok(EnpFrontEndShmKey.GetBuffer(), EnpFrontEndShmKey.GetBufferLen());

    GETINT(MAIN_SECTION, "EnpFrontEndShmSize", EnpFrontEndShmSize);
    GETSIZESTRING(MAIN_SECTION, "EnpFrontEndSocket", EnpFrontEndSocket);
    GETSIZESTRING(MAIN_SECTION, "EnpBackEndSocket", EnpBackEndSocket);

    GETSIZESTRING(MAIN_SECTION, "MpFrontEndShmKey", MpFrontEndShmKey);
 //   Ftok(MpFrontEndShmKey.GetBuffer(), MpFrontEndShmKey.GetBufferLen());
    //读取DB的配置信息

    GETINT(MAIN_SECTION, "MpFrontEndShmSize", MpFrontEndShmSize);
    GETSIZESTRING(MAIN_SECTION, "MpFrontEndSocket", MpFrontEndSocket);
    GETSIZESTRING(MAIN_SECTION, "MpBackEndSocket", MpBackEndSocket);
    GETSIZESTRING(MAIN_SECTION, "DBServer", szDBServer);

    iRet =  LoadLogConfig();

    if(iRet == 0)
    {
        iRet = LoadDynamicConfig();
    }
    return iRet;
}

int CDBConfig::ReloadConfig()
{
    int iRet =  LoadLogConfig();
    if(iRet == 0)
    {
        iRet = LoadDynamicConfig();
    }
    return iRet;
}

int CDBConfig::LoadDynamicConfig()
{

    string s;
    CTConfig cfg;
    int iRet = cfg.LoadConfig(FILE_CONFIG);
    if (iRet)
    {
        CT_THROW(("LoadConfig failed: %d", iRet));
        return -1;
    }

    CTSizeString<CT_PATH_MAX> sMainCommConfig;
    GETSIZESTRING(MAIN_SECTION, "DbCommonConfig", sMainCommConfig);
    char* commConfCstr = sMainCommConfig.Get();

    GETINTFROMFILE(commConfCstr,MAIN_SECTION, "InitDataFlushNum", m_iInitFlushNum);
    if (m_iInitFlushNum < 0 )
    {
        CT_THROW(("InitDataFlushNum < 0!"));
        return -1;
    }
    GETINTFROMFILE(commConfCstr,MAIN_SECTION, "MaxDataFlushNum", m_iMaxFlushNum);
    if (m_iMaxFlushNum < 0 )
    {
        CT_THROW(("MaxDataFlushNum < 0!"));
        return -1;
    }

	GETINTFROMFILE(commConfCstr,MAIN_SECTION, "InitStopFlushNum", m_iInitStopFlushNum);
	if (m_iInitStopFlushNum < 0 )
	{
		CT_THROW(("InitDataFlushNum < 0!"));
		return -1;
	}
	GETINTFROMFILE(commConfCstr,MAIN_SECTION, "MaxStopFlushNum", m_iMaxStopFlushNum);
	if (m_iMaxStopFlushNum < 0 )
	{
		CT_THROW(("MaxDataFlushNum < 0!"));
		return -1;
	}

    CT_INFO(("dynamic para InitDataFlushNum %d,MaxDataFlushNum %d stop para %d %d",
        m_iInitFlushNum,m_iMaxFlushNum,m_iInitStopFlushNum,m_iMaxStopFlushNum));   

    return 0;
}

int CDBConfig::LoadLogConfig()
{
	CTConfig cfg;
	int iRet = cfg.LoadConfig(FILE_CONFIG);
	if (iRet)
	{
		CT_THROW(("LoadConfig failed: %d", iRet));
	}

    int iLogFileNum = 0, iLogFileSize = 0;
	GETINT(MAIN_SECTION, "LogFileNum", iLogFileNum);
	GETINT(MAIN_SECTION, "LogFileSize", iLogFileSize);
	CT_NLOG->Init(ENamed, NULL, FILE_NORMALLOG, iLogFileSize, iLogFileNum);
	CT_ELOG->Init(ENamed, NULL, FILE_ERRORLOG, iLogFileSize, iLogFileNum);
	CT_STAT->Init(ENamed, NULL, FILE_STATLOG, iLogFileSize, iLogFileNum);
    CT_UPT->Init(ENamed, NULL, FILE_UPDATELOG, iLogFileSize, iLogFileNum);
	CT_STAT->SetFormat(ETime|ENewLine);

	// 设置filter
    string str;
	GETSTRING(MAIN_SECTION, "LogFormat", str)
	CT_NLOG->SetFormatByStr(str.c_str());
	CT_ELOG->SetFormatByStr(str.c_str());
    CT_UPT->SetFormatByStr("time|pid|newline");

	// 设置filter
	GETSTRING(MAIN_SECTION, "LogFilter", str)
	CT_NLOG->SetFilterByStr(str.c_str());
	CT_ELOG->SetFilterByStr(str.c_str());
    CT_UPT->SetFilterByStr("trace");

	CT_INFO(("LogFormat=%d LogFilter=%d", CT_NLOG->GetFormat(), CT_NLOG->GetFilter()));
    return 0;
}

#ifndef WIN32
    #include <sys/types.h>
    #include <sys/ipc.h>
#endif
void CDBConfig::Ftok(char* pszPathName, size_t iLen)
{
#ifndef WIN32
    key_t iKey = ftok(pszPathName, 0);
    if (iKey == -1)
    {
        CT_THROW(("ftok(%s) failed %d", pszPathName, CT_ERRNO));
    }

    ct_snprintf(pszPathName, iLen, "%d", iKey);
#endif
}
